﻿using SuperX.Common;
using SuperX.Common.APIManager;
using SuperX.Common.BasicService;
using SuperX.Common.Helper;
using SuperX.Common.Log;
using SuperX.Common.Object;
using SuperX.DataService;
using SuperX.DataService.Abstract;
using SuperX.Helper;
using SuperX.Helper.FileUtil;
using SuperX.Helper.PageBreak;
using SuperX.Helper.ServiceResponse;
using SuperX.DeviceService.Ledger;
using SuperX.DeviceService.Model;
using SuperX.SuperSocket;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;

namespace SuperX.DeviceService
{
    [PythonScript(label = "DeviceController", apply = "DeviceController", type = "keyword", detail = "")]
    public class DeviceController : DynamicApiController
    {
        private const string _parentNode = "Server";
        private readonly DeviceServer _server;
        private IProject _project = BasicServiceManager.GetProjService().Project;

        public DeviceController(DeviceServer server)
        {
            _server = server;
            Name = nameof(DeviceController);
        }

        [WebApi("获取驱动配置", "", "")]
        public ApiResponse<List<DriverConfig>> GetDriverGroups()
        {
            var res = _server.Config.DriverGroups.Values.ToResponse();
            return res;
        }

        [WebApi("获取驱动默认寄存器列表", "寄存器", "寄存器键值")]
        public ApiResponse<Dictionary<string, string>> GetDriverRegester(string driverName)
        {
            ApiResponse<Dictionary<string, string>> res = new ApiResponse<Dictionary<string, string>>();
            Dictionary<string, string> data = new Dictionary<string, string>();
            if (!_project.Objects.ContainsKey(driverName)) return ApiResponse<Dictionary<string, string>>.Fail("无法找到驱动配置！");
            var driverConfig = _project.Objects[driverName] as DriverConfig;
            if (driverConfig == null) return ApiResponse<Dictionary<string, string>>.Fail("无法找到驱动配置！");
            var driver = _server.DataManager.GetDriver(driverConfig.AssemblyName, driverConfig.ClassFullName, driverConfig.Argument);
            if (driver == null) return ApiResponse<Dictionary<string, string>>.Fail("无法找到驱动对象！");
            data = driver.GetRegester();
            res.Data = data;
            return res;
        }

        [PythonScript(label = "GetTagValue", apply = "GetTagValue", type = "keyword", detail = "")]
        [WebApi("读取单个值", "变量全名", "当前值")]
        public ApiResponse<object> GetTagValue(string tagName)
        {
            ApiResponse<object> res = new ApiResponse<object>();
            //if (!_server.DataManager.IOTagGroup.ContainsKey(tagName)) return ApiResponse<object>.Fail("变量名称不正确无法找到变量");
            if (!_project.Objects.ContainsKey(tagName)) return ApiResponse<object>.Fail("变量名称不正确无法找到变量");
            IIOTag tag = _project.Objects[tagName] as IIOTag;
            if (tag == null) return ApiResponse<object>.Fail("变量名称不正确无法找到变量");
            res.Data = tag.Value;
            return res;
        }

        [PythonScript(label = "GetBatchTagValue", apply = "GetBatchTagValue", type = "keyword", detail = "")]
        [WebApi("读取多个变量值", "变量全名数组", "数据结果")]
        public ApiResponse<List<BaseTagOutput>> GetBatchTagValue(List<string> tagFullNames)
        {
            return _server.DataManager.GetBatchTagValue(tagFullNames);
        }

        [PythonScript(label = "GetTagsValue", apply = "GetTagsValue", type = "keyword", detail = "")]
        [WebApi("读取多个变量值设备诊断用", "变量全名,变量值", "数据结果")]
        public ApiResponse<TagRecordOutDto> GetTagsValue(List<string> tagFullNames)
        {
            return _server.DataManager.GetTagsValue(tagFullNames);
        }

        [PythonScript(label = "Write", apply = "Write", type = "keyword", detail = "")]
        [WebApi("写入单个值", "变量全名,变量值", "写入结果")]
        public ApiResponse<string> Write(string tagName, Object value)
        {
            try
            {
                var res = _server.DataManager.Write(tagName, value);
                switch (res)
                {
                    case ErrorCode.WriteNotSupport:
                        return ApiResponse<string>.Fail(ErrorMessage.WriteNotSupport);
                }
                if (res != 0)
                    return ApiResponse<string>.Fail("变量写入失败");
            }
            catch (Exception ex)
            {
                Logger.WarnException(ex);
            }
            return ApiResponse<string>.Success();
        }

        [PythonScript(label = "Write", apply = "Write", type = "keyword", detail = "")]
        [WebApi("批量写入值", "变量名,变量值,分组名", "写入结果")]
        public ApiResponse<string> BatchWrite(string deviceCode, Dictionary<string, object> dic, string groupName = "Defalut")
        {
            try
            {
                var device = _server.DataManager.DriverGroups.Values.Where(a => a.DriverNO == deviceCode).FirstOrDefault();
                if (device == null) return ApiResponse<string>.Fail(ErrorMessage.DeviceNotFound);
                List<int> writeRes = new List<int>();
                foreach (var item in dic)
                {
                    var tagName = (device as IBasicObject).FullName + "." + groupName + "." + item.Key;
                    var res = _server.DataManager.Write(tagName, item.Value);
                    writeRes.Add(res);
                }
                if (!writeRes.Contains(0))
                    return ApiResponse<string>.Fail("变量写入失败");
            }
            catch (Exception ex)
            {
                Logger.WarnException(ex);
            }
            return ApiResponse<string>.Success();
        }

        [PythonScript(label = "Write", apply = "Write", type = "keyword", detail = "")]
        [WebApi("批量写入值", "变量名,变量值,分组名", "写入结果")]
        public ApiResponse<bool> DeviceApi(string deviceCode, JObject values)
        {
            try
            {
                var device = _server.DataManager.DriverGroups.Values.FirstOrDefault(a => a.DriverNO == deviceCode);
                if (device == null) return ApiResponse<bool>.Fail(ErrorMessage.DeviceNotFound);
                if (device is IApiDriver apiDevice)
                {
                    apiDevice.DeviceApi(values);
                    return ApiResponse<bool>.Success("调用成功", true);
                }
            }
            catch (Exception ex)
            {
                Logger.WarnException(ex);
                return ApiResponse<bool>.Fail(ex.Message);
            }
            return ApiResponse<bool>.Fail("调用失败");
        }

        [WebApi("获取默认驱动配置", "无参数", "返回驱动数组")]
        public ApiResponse<List<BaseTreeNode>> GetDefaultDriverConfig()
        {
            return _server.DataManager.GetDefaultDriverConfig().ToResponse();
        }

        [WebApi("停止运行驱动", "", "执行结果")]
        public ApiResponse<bool> StopDriver()
        {
            return new ApiResponse<bool> { Data = _server.DataManager.Stop() };
        }

        [WebApi("获取驱动分组树", "", "返回Tree对象")]
        public ApiResponse<List<TreeModel>> GetDriverTree(string driverName = "")
        {
            var driverTrees = new List<TreeModel>();
            var drivers = (_server.DataManager.Config.DriverGroups).Values.ToList();
            if (!string.IsNullOrEmpty(driverName))
            {
                drivers = drivers.Where(x => x.Name == driverName).ToList();
            }
            foreach (var driver in drivers)
            {
                var createdByTemplate = driver.TemplateId is null ? false : true;
                TreeModel treeModel = new TreeModel();
                treeModel.Key = driver.FullName;
                treeModel.Type = (int)DriverTree.Driver;
                treeModel.Parentkey = string.IsNullOrEmpty(driver.NodeKey) ? _parentNode : driver.NodeKey;
                treeModel.Name = driver.Name;
                treeModel.CreatedByTemplate = createdByTemplate;
                treeModel.TemplateSync = driver.TemplateSync;
                treeModel.AddressExtend = driver.AddressExtend;
                foreach (var item in driver.Groups)
                {
                    driverTrees.Add(new TreeModel()
                    {
                        Parentkey = driver.FullName,
                        Key = item.FullName,
                        Name = item.Name,
                        Type = (int)DriverTree.DriverGroup,
                        SystemType = item.GroupType,
                        CreatedByTemplate = createdByTemplate,
                        TemplateSync = driver.TemplateSync,
                        AddressExtend = treeModel.AddressExtend,
                    });
                }
                driverTrees.Add(treeModel);
            }
            foreach (var item in _server.DataManager.Config.DeviceNodeNames.Values)
            {
                TreeModel treeModel = new TreeModel();
                treeModel.Key = item.Key;
                treeModel.Type = string.IsNullOrEmpty(item.Parentkey) ? (int)DriverTree.Node : (int)DriverTree.ChildNode;
                treeModel.Parentkey = string.IsNullOrEmpty(item.Parentkey) ? _parentNode : item.Parentkey;
                treeModel.Name = item.Name;
                driverTrees.Add(treeModel);
            }
            driverTrees.Add(new TreeModel() { Parentkey = "0", Key = _parentNode, Type = (int)DriverTree.Server, Name = "设备集合" });
            var res = TreeHelper.BulidTreeByRecursive(driverTrees, new List<TreeModel>(), "0");
            return res.ToResponse();
        }

        [WebApi("获取运行时驱动树", "无", "返回树对象")]
        public ApiResponse<List<TreeModel>> GetRunTimeDriverTree(string driverName = "")
        {
            var driverTrees = new List<TreeModel>();
            var drivers = _server.DataManager.Drivers;
            if (!string.IsNullOrEmpty(driverName))
            {
                drivers = drivers.Where(x => x.Name == driverName);
            }
            foreach (var driver in drivers)
            {
                var basicObject = driver as IBasicObject;
                TreeModel treeModel = new TreeModel();
                treeModel.Key = basicObject.FullName;
                treeModel.Type = 1;
                treeModel.Parentkey = string.IsNullOrEmpty(driver.NodeKey) ? _parentNode : driver.NodeKey;
                treeModel.Name = driver.Name;
                treeModel.ConfigKey = driver.ConfigName;
                treeModel.ConectState = GetDeviceState(treeModel.Key).Data;
                foreach (IBasicObject item in driver.Groups)
                {
                    driverTrees.Add(new TreeModel()
                    {
                        Parentkey = basicObject.FullName,
                        Key = item.FullName,
                        Name = item.Name,
                        ConfigKey = (item as IGroup).ConfigName,
                        ConfigParentkey = treeModel.ConfigKey,
                        Type = 2,
                    });
                }
                driverTrees.Add(treeModel);
            }
            foreach (var item in _server.DataManager.Config.DeviceNodeNames.Values)
            {
                TreeModel treeModel = new TreeModel();
                treeModel.Key = item.Key;
                treeModel.Type = string.IsNullOrEmpty(item.Parentkey) ? (int)DriverTree.Node : (int)DriverTree.ChildNode;
                treeModel.Parentkey = string.IsNullOrEmpty(item.Parentkey) ? _parentNode : item.Parentkey;
                treeModel.Name = item.Name;
                driverTrees.Add(treeModel);
            }
            driverTrees.Add(new TreeModel() { Parentkey = "0", Key = _parentNode, Type = 0, Name = "设备集合" });
            var res = TreeHelper.BulidTreeByRecursive(driverTrees, new List<TreeModel>(), "0");
            return res.ToResponse();
        }

        [WebApi("获取运行时驱动树-仅显示驱动", "无", "返回树对象")]
        public ApiResponse<List<TreeModel>> GetRunTimeOnlyDriver()
        {
            var driverTrees = new List<TreeModel>();
            var drivers = _server.DataManager.Drivers;
            foreach (var driver in drivers)
            {
                var basicObject = driver as IBasicObject;
                TreeModel treeModel = new TreeModel();
                treeModel.Key = basicObject.FullName;
                treeModel.Type = 1;
                treeModel.Parentkey = string.IsNullOrEmpty(driver.NodeKey) ? _parentNode : driver.NodeKey;
                treeModel.Name = driver.Name;
                driverTrees.Add(treeModel);
            }
            foreach (var item in _server.DataManager.Config.DeviceNodeNames.Values)
            {
                var exists = drivers.Where(a => a.NodeKey == item.Key).FirstOrDefault();
                if (exists == null) continue;
                TreeModel treeModel = new TreeModel();
                treeModel.Key = item.Key;
                treeModel.Type = 0;
                treeModel.Parentkey = _parentNode;
                treeModel.Name = item.Name;
                driverTrees.Add(treeModel);
            }
            driverTrees.Add(new TreeModel() { Parentkey = "0", Key = _parentNode, Type = 0, Name = "设备集合" });
            var res = TreeHelper.BulidTreeByRecursive(driverTrees, new List<TreeModel>(), "0");
            return res.ToResponse();
        }

        [WebApi("新增驱动信息", "驱动对象", "返回bool")]
        public ApiResponse<string> AddDriver(DriverConfig driver)
        {
            driver.Enabled = true;
            driver.NodeKey = string.IsNullOrEmpty(driver.NodeKey) ? _parentNode : driver.NodeKey;
            return _server.DataManager.AddDriver(driver);
        }

        [WebApi("获取结构树", "驱动对象", "返回bool")]
        public ApiResponse<List<TreeModel>> GetAddressTrees(string deviceFullName)
        {
            return _server.DataManager.GetTree(deviceFullName);
        }

        [WebApi("获取节点表格", "驱动对象,父节点", "地址表格")]
        public ApiResponse<List<GridItem>> GetAddressGrid(string deviceFullName, string parentNode)
        {
            return _server.DataManager.GetGrid(deviceFullName, parentNode);
        }

        [WebApi("删除驱动信息", "驱动Name", "返回bool")]
        public ApiResponse<bool> DelDriver(string driverName)
        {
            if (string.IsNullOrEmpty(driverName))
                return ApiResponse<bool>.Fail("参数不合法！");
            var Driver = _project.Objects[driverName] as DriverConfig;
            if (Driver == null) return ApiResponse<bool>.Fail("删除失败，未找到此驱动！");
            foreach (var group in Driver.Groups.Values)
            {
                var Group = _project.Objects[group.FullName] as GroupConfig;
                foreach (var tag in Group.TagGroups.Values)
                {
                    var tagFullName = tag.FullName.Replace("Tag", "DRV");
                    var res = RpcProcessor.ExecutionAction("Alarm", "GetAlarmItemByTagFullName", new object[] { tagFullName });
                    if ((res as ApiResponse<string>).Code == ResponseCode.Failed) continue;
                    if (res != null) return ApiResponse<bool>.Fail("删除失败，此驱动中的变量有告警配置，请先删除对应的告警配置！");
                }
            }
            _server.DataManager.Config.DriverGroups.Remove(Driver);
            return ApiResponse<bool>.Success("删除成功！");
        }

        [WebApi("更新驱动信息", "驱动Name,驱动对象", "返回bool")]
        public ApiResponse<string> UpdateDriver(string driverName, DriverConfig driver)
        {
            Helper.Validation.ValidationMain.ScanIsValid(driver);
            var Driver = _project.Objects[driverName] as DriverConfig;
            if (Driver == null) return ApiResponse<string>.Fail("更新失败，未找到此驱动！");
            _server.DataManager.UpdateDriver(driver);
            ConfigReflectionHelper.AutoMapping(Driver, driver, skip: "Parent,Item,FullName,Groups");    //修改驱动时忽略前端分组，否则会替换一个空的分组或默认分组
            return ApiResponse<string>.Success();
        }

        [WebApi("查询驱动信息", "驱动Name", "驱动对象")]
        public ApiResponse<DriverConfig> GetDriver(string driverName)
        {
            var Driver = _project.Objects[driverName] as DriverConfig;
            if (Driver == null) return ApiResponse<DriverConfig>.Fail("查询失败，未找到此驱动！");
            JObject config = JObject.FromObject(Driver);
            config.Remove("GroupConfigs");
            return ApiResponse<DriverConfig>.Success(data: Driver);
        }

        [WebApi("新增分组信息", "驱动Name,驱动对象", "返回bool")]
        public ApiResponse<string> AddGroup(string driverName, GroupConfig groupConfig)
        {
            var Driver = _project.Objects[driverName] as DriverConfig;
            if (Driver == null) return ApiResponse<string>.Fail("添加失败，未找到此驱动！");
            Helper.Validation.ValidationMain.ScanIsValid(groupConfig);
            Driver.Groups.Add(groupConfig);
            return ApiResponse<string>.Success();
        }

        [WebApi("删除分组信息", "驱动Name,分组Name", "返回bool")]
        public ApiResponse<object> DelGroup(string driverName, string groupName)
        {
            var Driver = _project.Objects[driverName] as DriverConfig;
            var Group = _project.Objects[groupName] as GroupConfig;
            if (Driver == null || Group == null) return ApiResponse<object>.Fail("删除失败，未找到此驱动或者分组！");
            var isDel = Driver.Groups.Remove(Group);
            return ApiResponse<object>.Success(data: isDel);
        }

        [WebApi("更新分组信息", "驱动Name,分组Name,分组对象", "返回bool")]
        public ApiResponse<string> UpdateGroup(string driverName, string groupName, GroupConfig groupConfig)
        {
            Helper.Validation.ValidationMain.ScanIsValid(groupConfig);
            var Driver = _project.Objects[driverName] as DriverConfig;
            var Group = _project.Objects[groupName] as GroupConfig;
            groupConfig.GroupType = Group.GroupType;
            if (Driver == null || Group == null) return ApiResponse<string>.Fail("更新失败，未找到此驱动或者分组！");
            ConfigReflectionHelper.AutoMapping(Group, groupConfig, skip: "TagGroups,Item,FullName");
            return ApiResponse<string>.Success();
        }

        [WebApi("查询分组信息", "驱动Name,分组Name", "返回bool")]
        public ApiResponse<JObject> GetGroup(string driverName, string groupName)
        {
            var Driver = _project.Objects[driverName] as DriverConfig;
            var Group = _project.Objects[groupName] as GroupConfig;
            if (Driver == null || Group == null) return ApiResponse<JObject>.Fail("查询失败，未找到此驱动或者分组！");
            JObject config = JObject.FromObject(Group);
            config.Remove("TagMetaDatas");
            return ApiResponse<JObject>.Success(data: config);
        }

        [PythonScript(label = "GetTagsName", apply = "GetTagsName", type = "keyword", detail = "this.hintRender")]
        [WebApi("获取所有Tags名称", "", "返回List string")]
        public ApiResponse<List<string>> GetTagsName()
        {
            List<string> Strings = new List<string>();
            var aaa = BasicServiceManager.GetProjService().Project.Objects;
            foreach (var item in BasicServiceManager.GetProjService().Project.Objects)
            {
                if (item.Value.GetType().BaseType.Name == "IOTag")
                    Strings.Add(item.Key);
            }
            return Strings.ToResponse();
        }

        [WebApi("新增Tag", "设备Name,组Name", "返回bool")]
        public ApiResponse<string> AddTag(string driverName, string groupName, TagConfig tag)
        {
            Helper.Validation.ValidationMain.ScanIsValid(tag);
            var Driver = _project.Objects[driverName] as DriverConfig;
            var Group = _project.Objects[groupName] as GroupConfig;
            if (Driver == null || Group == null) return ApiResponse<string>.Fail("新增失败，未找到此驱动或者分组！");
            var driverBase = _server.DataManager.GetDriver(Driver.AssemblyName, Driver.ClassFullName, Driver.Argument);
            tag.Address = driverBase.AddressCombin(tag.Regester, tag.No);
            if (tag.TagType == TagType.Normal)
            {
                var checkResult = driverBase.CheckAddressLegal(tag.Address, tag.DataType);
                if (!checkResult) return ApiResponse<string>.Fail("新增失败，寄存器地址校验不通过！");
            }
            else if (tag.TagType == TagType.Exclusive)
            {
                tag.Regester = "N/";
                tag.No = "A";
                tag.Address = "N/A";
            }
            Group.TagGroups.Add(tag);
            return ApiResponse<string>.Success();
        }

        [WebApi("批量新增Tag", "设备Name,组Name", "返回bool")]
        public ApiResponse<string> BatchAddTag(string driverName, string groupName, TagConfig tag, int quantity)
        {
            Helper.Validation.ValidationMain.ScanIsValid(tag);
            var Driver = _project.Objects[driverName] as DriverConfig;
            var Group = _project.Objects[groupName] as GroupConfig;
            if (Driver == null || Group == null) return ApiResponse<string>.Fail("新增失败，未找到此驱动或者分组！");
            var driverBase = _server.DataManager.GetDriver(Driver.AssemblyName, Driver.ClassFullName, Driver.Argument);
            tag.Address = driverBase.AddressCombin(tag.Regester, tag.No);
            var checkResult = driverBase.CheckAddressLegal(tag.Address, tag.DataType);
            if (!checkResult) return ApiResponse<string>.Fail("新增失败，寄存器地址校验不通过！");
            if (!_server.DataManager.BatchAddTag(Group, tag, quantity, out string message))
                return ApiResponse<string>.Fail(message);
            return ApiResponse<string>.Success();
        }

        [WebApi("获取需要复制的Tag名称", "设备Name,组Name", "返回bool")]
        public ApiResponse<string> GetCopyTagName(string driverName, string groupName, string tagName)
        {
            var Driver = _project.Objects[driverName] as DriverConfig;
            var Group = _project.Objects[groupName] as GroupConfig;
            if (Driver == null || Group == null) return ApiResponse<string>.Fail("新增失败，未找到此驱动或者分组！");
            var copyTagName = _server.DataManager.GetTagNames(Group, tagName, 1)?.First();
            return ApiResponse<string>.Success(data: copyTagName);
        }

        [WebApi("删除Tag", "设备Name,组Name,Tag的Name", "返回true或false")]
        public ApiResponse<string> DelTag(string driverName, string groupName, string tagName)
        {
            var Driver = _project.Objects[driverName] as DriverConfig;
            var Group = _project.Objects[groupName] as GroupConfig;
            var tag = Group.TagGroups[tagName];
            if (Driver == null || Group == null || tag == null) return ApiResponse<string>.Fail("删除失败，未找到此变量或者分组！");
            var tagFullName = groupName.Replace("Tag", "DRV") + "." + tagName;
            var res = RpcProcessor.ExecutionAction("Alarm", "GetAlarmItemByTagFullName", new object[] { tagFullName });
            if (res != null) return ApiResponse<string>.Fail("删除失败，此变量有告警配置，请先删除告警配置！");
            Group.TagGroups.Remove(tag);
            return ApiResponse<string>.Success();
        }

        [WebApi("批量删除Tag", "设备Name,组Name,Tag的Name", "返回true或false")]
        public ApiResponse<string> BatchDelTag(string driverName, string groupName, string[] tagNames)
        {
            if (string.IsNullOrEmpty(driverName) || string.IsNullOrEmpty(groupName) || !tagNames.Any())
                return ApiResponse<string>.Fail("参数不合法！");
            var Driver = _project.Objects[driverName] as DriverConfig;
            var Group = _project.Objects[groupName] as GroupConfig;
            //var tag = Group.TagGroups[tagNames];
            if (Driver == null || Group == null) return ApiResponse<string>.Fail("删除失败，未找到此驱动或者分组！");
            foreach (var item in tagNames)
            {
                if (Group.TagGroups[item] is TagConfig tagConfig)
                {
                    Group.TagGroups.Remove(tagConfig);
                }
            }
            return ApiResponse<string>.Success();
        }

        [WebApi("修改Tag", "设备Name,组Name,TagName,tag对象", "")]
        public ApiResponse<string> UpdateTag(string driverID, string groupID, string TagName, TagConfig tag)
        {
            var driver = _project.Objects[driverID] as DriverConfig;
            var group = _project.Objects[groupID] as GroupConfig;
            var deltag = group.TagGroups[TagName];
            if (driver == null || group == null || deltag == null) return ApiResponse<string>.Fail("修改失败！");
            var driverBase = _server.DataManager.GetDriver(driver.AssemblyName, driver.ClassFullName, driver.Argument);
            if (tag.Regester == null) tag.Regester = "";
            tag.Address = driverBase.AddressCombin(tag.Regester, tag.No);
            ConfigReflectionHelper.AutoMapping(deltag, tag, skip: "Item,FullName");
            return ApiResponse<string>.Success();
        }

        [WebApi("获取配置文件Tags", "驱动名,组名", "返回Tag数组")]
        public ApiResponse<PageResult<TagConfig>> GetTagInfoByGroupId(TagQueryInputDto input)
        {
            if (input.DriverKey == "-1" || input.GroupKey == "-1") return ApiResponse<PageResult<TagConfig>>.Success(data: new PageResult<TagConfig>());//前端要求
            return ApiResponse<PageResult<TagConfig>>.Success(data: _server.DataManager.GetGroupInfo(input));
        }

        [WebApi("获取运行时Tags", "驱动名,组名", "返回Tag数组")]
        public ApiResponse<PageResult<RunTimeTagModel>> GetRunTimeTagInfo(TagQueryInputDto input)
        {
            if (input.DriverKey == "-1" || input.GroupKey == "-1") return ApiResponse<PageResult<RunTimeTagModel>>.Success(data: new PageResult<RunTimeTagModel>());//前端要求
            return ApiResponse<PageResult<RunTimeTagModel>>.Success(data: _server.DataManager.GetRunTimeTagInfo(input));
        }

        [PythonScript(label = "GetRunTimeAllTag", apply = "GetRunTimeAllTag", type = "keyword", detail = "")]
        [WebApi("过去运行时所有Tag", "", "返回Tag数组")]
        public ApiResponse<Dictionary<string, IIOTag>> GetRunTimeAllTag()
        {
            return _server.DataManager.IOTagGroup.ToResponse();
        }

        [WebApi("获取数据类型", "", "返回数据类型对象集合")]
        public ApiResponse<List<object>> GetDataType()
        {
            List<object> list = new List<object>();
            foreach (DataType item in Enum.GetValues(typeof(DataType)))
            {
                list.Add(new { Key = item.ToString(), Value = (int)item });
            }
            return list.ToResponse();
        }

        [WebApi("获取驱动读写模式", "", "返回数据类型对象集合")]
        public ApiResponse<List<object>> GetReadWriteMode()
        {
            List<object> list = new List<object>();
            foreach (ReadWriteMode item in Enum.GetValues(typeof(ReadWriteMode)))
            {
                list.Add(new { Key = item.ToString(), Value = (int)item });
            }
            return list.ToResponse();
        }

        [WebApi("保存配置到文件", "", "返回true或false")]
        public ApiResponse<object> SaveConfig()
        {
            UpdateDriverNO();
            var webSocketConfigSave = (RpcProcessor.ExecutionAction("HDA", "SaveTagsKey", new object[] { _server.DataManager.GetConfigTags() }) as ApiResponse<bool>)?.Data;
            if (webSocketConfigSave == false)
                return ApiResponse<object>.Fail("变量实时刷新配置存储失败！");
            return ApiResponse<object>.Success(data: _server.Save());
        }

        [WebApi("获取配置", "", "返回true或false")]
        public ApiResponse<Dictionary<string, bool>> GetConfigTagList()
        {
            var data = _server.DataManager.GetConfigTags();
            return data.ToResponse();
        }

        private void UpdateDriverNO()
        {
            var equipments = GetEquipments(new EquipmentQueryInput { PageSize = 10000 }).Data.Rows;
            foreach (var item in equipments)
            {
                if (string.IsNullOrEmpty(item.fullName)) continue;
                if (!_project.Objects.ContainsKey(item.fullName)) continue;
                var device = _server.DataManager.DriverGroups.Values.FirstOrDefault(a => (a as IBasicObject).FullName == item.fullName);
                device.DriverNO = item.code;
                if (!_project.Objects.ContainsKey(device.ConfigName)) return;
                var driverConfig = _project.Objects[device.ConfigName] as DriverConfig;
                driverConfig.DriverNO = device.DriverNO;
            }
        }

        [WebApi("获取IntergrationServer配置信息", "无", "")]
        public ApiResponse<JObject> GetIntergrationConfig()
        {
            JObject config = JObject.FromObject(_server.Config);
            config.Remove("DriverConfigs");
            config.Remove("TagMetaDatas");
            return config.ToResponse();
        }

        [WebApi("修改配置文件", "配置文件的key,配置文件的value", "")]
        public ApiResponse<string> SetIntergrationConfig(string key, object value)
        {
            var config = _server.Config;
            ConfigReflectionHelper.UpdateValueByPath(config, key, value);
            if (_server.Save())
                return ApiResponse<string>.Success();
            else
                return ApiResponse<string>.Fail();
        }

        [WebApi("获取运行时Tags", "无", "")]
        public ApiResponse<Dictionary<string, IDriver>> GetRunTimeTag()
        {
            var devices = _server.DataManager.DriverGroups.Values;
            var data = devices.ToDictionary(k => (k as BasicObject).FullName, kv => kv);
            return new ApiResponse<Dictionary<string, IDriver>> { Data = data };
        }

        [WebApi("获取机器码", "无", "机器码")]
        public ApiResponse<string> GetMachineCode()
        {
            return Machine.GetMachineCode().ToResponse();
        }

        [WebApi("获取授权信息", "无", "授权驱动集合")]
        public ApiResponse<List<RegDriverInfo>> GetAuthorization()
        {
            var data = _server.DataManager.CheckReg();
            if (data == null) return new ApiResponse<List<RegDriverInfo>> { Data = new List<RegDriverInfo>(), Message = "无法找到授权信息" };
            var res = data.RegBase.DriverRegInfo
                .Select(a =>
                new RegDriverInfo
                {
                    Name = a.DriverFullName,
                    Number = a.RegOfNumber,
                    ExpiryDate = data.RegBase.ExpiryDate
                }).ToList();
            return new ApiResponse<List<RegDriverInfo>> { Data = res };
        }

        [WebApi("获取驱动授权总数", "无", "驱动数量")]
        public ApiResponse<int> GetAuthorizationNumber()
        {
            var resData = 0;
            var data = _server.DataManager.CheckReg();
            if (data == null) return resData.ToResponse();
            return data.RegBase.DriverRegInfo.Select(a => a.RegOfNumber).Sum().ToResponse();
        }

        [WebApi("下载授权文件", "无", "下载结果")]
        public ApiResponse<bool> DownloadAuthorization(string path)
        {
            if (!File.Exists(path)) return new ApiResponse<bool> { Data = false, Message = "文件不存在" };
            var fileByte = File.ReadAllBytes(path);
            var destPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "IOT.key");
            var res = FileHelper.ByteToFile(fileByte, destPath);
            return new ApiResponse<bool> { Data = res };
        }

        [WebApi("获取设备连接状态", "设备全路径", "连接结果:true:连接成功")]
        public ApiResponse<bool> GetDeviceState(string deviceName)
        {
            var device = _server.DataManager.DriverGroups.Values.FirstOrDefault(a => (a as BasicObject).FullName == deviceName);
            if (device == null) return ApiResponse<bool>.Fail("设备不存在或设备名称错误！");
            return new ApiResponse<bool>() { Data = !device.IsClosed };
        }

        [WebApi("根据驱动导出点位", "驱动名称", "直接返回blob")]
        public string ExportByDriver(string driverName)
        {
            DataSet ds = new DataSet();
            var hosts = _project.Objects[driverName] as DriverConfig;
            foreach (var item in hosts.Groups.Values)
            {
                var tagList = item.TagGroups.Values.Where(t => t.TagType != TagType.System).ToList();
                var tb = Helper.NOPI.ListTableTools.ListToTable(tagList, "ServiceType,Parent,FullName,Identity,ObjectState");
                if (tb.Columns.Contains("Name")) tb.Columns["Name"].SetOrdinal(0);
                tb.TableName = item.Name;
                ds.Tables.Add(tb);
            }
            var exportPath = Helper.NOPI.ExcelHelperForCs.ExportToExcel(ds);
            return exportPath;
        }

        [WebApi("根据分组导出点位", "驱动名称,分组名称", "直接返回blob")]
        public string ExportByGroup(string driverName, string groupName)
        {
            DataSet ds = new DataSet();
            var hosts = _project.Objects[driverName] as DriverConfig;
            var group = _project.Objects[groupName] as GroupConfig;
            var tagList = group.TagGroups.Values.Where(t => t.TagType != TagType.System).ToList();
            var tb = Helper.NOPI.ListTableTools.ListToTable(tagList, "ServiceType,Parent,FullName,Identity,ObjectState");
            if (tb.Columns.Contains("Name")) tb.Columns["Name"].SetOrdinal(0);
            tb.TableName = group.Name;
            ds.Tables.Add(tb);
            var exportPath = Helper.NOPI.ExcelHelperForCs.ExportToExcel(ds);
            return exportPath;
        }

        [WebApi("文件导入", "", "")]
        public ApiResponse<string> FileImport(string deviceName, Helper.NOPI.UpLoadFileInfo[] FileName)
        {
            if (!FileName.Any()) return ApiResponse<string>.Fail("未收到任何待导入文件！");
            if (!(_project.Objects[deviceName] is DriverConfig driver))
                return ApiResponse<string>.Fail("设备不存在或设备名称错误！");
            var msg = _server.DataManager.FileImport(driver, FileName.First().LocalFileName);
            if (string.IsNullOrEmpty(msg))
                return ApiResponse<string>.Success("导入成功！");
            return ApiResponse<string>.Fail(msg + "，导入失败！");
        }

        [WebApi("获取PLC读取文件路径类型", "", "")]
        public ApiResponse<List<EnumEntity>> GetPLCPathType()
        {
            var plcPathType = EnumToArrays.EnumToArray<Helper.PathType>();
            if (plcPathType.Any()) plcPathType.Remove(plcPathType.FirstOrDefault(p => p.Key == "FTP"));
            return plcPathType.ToResponse();
        }

        [WebApi("获取PLC文件解析的工作模式", "", "")]
        public ApiResponse<List<EnumEntity>> GetWorkModel()
        {
            return EnumToArrays.EnumToArray<WorkModel>().ToResponse();
        }

        [WebApi("获取Python编辑器提示信息", "", "返回提示集合")]
        public ApiResponse<List<PythonScriptModel>> GetPythonDisplay()
        {
            List<PythonScriptModel> list = _server.GetPythonScripts();
            return list.ToResponse();
        }

        [WebApi("获取IOT状态", "", "执行结果")]
        public ApiResponse<IOTState> GetIOTState()
        {
            return _server.DataManager.GetIOTState().ToResponse();
        }

        [WebApi("获取当前CPU使用率", "", "第一个是值第二个是单位")]
        public ApiResponse<string[]> GetCurrentCPU()
        {
            var result = new string[2] { _server.DataManager.GetCurrentCPU(), "%" };
            return result.ToResponse();
        }

        [WebApi("获取当前内存使用率", "", "第一个是值第二个是单位")]
        public ApiResponse<string[]> GetCurrentMemory()
        {
            var result = new string[2] { _server.DataManager.GetCurrentMemory(), "MB" };
            return result.ToResponse();
        }

        #region 分组业务

        [WebApi("增加节点", "", "")]
        public ApiResponse<bool> AddNode(string nodeName, string ParentNodeName = "")
        {
            var node = new TreeModel();
            var config = _server.DataManager.Config.DeviceNodeNames;
            var deviceName = _server.DataManager.Config.DriverGroups.Values.Where(a => a.Name == nodeName).FirstOrDefault();
            if (config.ContainsKey(nodeName) || deviceName != null) return ApiResponse<bool>.Fail("已存在重名分组或设备名！");
            node.Key = nodeName;
            node.Name = nodeName;
            if (ParentNodeName != "") node.Parentkey = ParentNodeName;
            config[node.Name] = node;
            return ApiResponse<bool>.Success("添加成功！");
        }

        [WebApi("编辑节点", "", "")]
        public ApiResponse<bool> EditNode(string oldName, string nodeName)
        {
            var config = _server.DataManager.Config.DeviceNodeNames;
            if (!config.ContainsKey(oldName)) return ApiResponse<bool>.Fail("不存在该节点！");
            if (config.ContainsKey(nodeName)) return ApiResponse<bool>.Fail("新名称重复！");
            var exists = config[oldName];
            exists.Key = nodeName;
            exists.Name = nodeName;
            config.Remove(oldName);
            config[nodeName] = exists;
            var drivers = _server.DataManager.Config.DriverGroups;
            foreach (var driver in drivers)
            {
                if (driver.NodeKey == oldName)
                    driver.NodeKey = nodeName;
            }
            foreach (var node in config.Values)
            {
                if (node.Parentkey == oldName)
                    node.Parentkey = nodeName;
            }
            return ApiResponse<bool>.Success("修改成功！");
        }

        [WebApi("删除节点", "", "")]
        public ApiResponse<bool> DeleteNode(string oldName)
        {
            var config = _server.DataManager.Config.DeviceNodeNames;
            if (!config.ContainsKey(oldName)) return ApiResponse<bool>.Fail("不存在该节点！");
            var exists = _server.DataManager.Config.DriverGroups.Values.Where(a => a.NodeKey == oldName).FirstOrDefault();
            if (exists != null) return ApiResponse<bool>.Fail("节点下存在设备，请先删除设备！");
            config.Remove(oldName);
            return ApiResponse<bool>.Success("删除成功！");
        }

        [WebApi("获取节点", "", "")]
        public ApiResponse<JArray> GetNode()
        {
            var driverTrees = new List<TreeModel>();
            driverTrees.Add(new TreeModel() { Parentkey = "0", Key = _parentNode, Type = (int)DriverTree.Server, Name = "设备集合" });
            foreach (var item in _server.DataManager.Config.DeviceNodeNames.Values)
            {
                TreeModel treeModel = new TreeModel();
                treeModel.Key = item.Key;
                treeModel.Type = (int)DriverTree.Node;
                treeModel.Parentkey = _parentNode;
                treeModel.Name = item.Name;
                driverTrees.Add(treeModel);
            }
            return JArray.FromObject(driverTrees.Select(x =>
            {
                return new { x.Name, x.Key };
            })).ToResponse();
        }

        #endregion 分组业务

        #region 设备台账

        [WebApi("获取设备集合", "", "")]
        public ApiResponse<PageResult<EquipmentLedger>> GetEquipments(EquipmentQueryInput input)
        {
            ApiResponse<PageResult<EquipmentLedger>> res = new ApiResponse<PageResult<EquipmentLedger>>();
            res.Data = _server.EquipmentManager.GetEquipments(input);
            return res;
        }

        [WebApi("增加设备", "设备对象", "执行结果")]
        public ApiResponse<bool> AddEquipment(EquipmentLedger equipmentLedger)
        {
            return _server.EquipmentManager.Add(equipmentLedger);
        }

        [WebApi("移除设备", "设备对象", "执行结果")]
        public ApiResponse<bool> RemoveEquipment(string code)
        {
            return _server.EquipmentManager.Remove(code);
        }

        [WebApi("更新设备", "设备对象", "执行结果")]
        public ApiResponse<bool> UpdateEquipment(string code, EquipmentLedger equipmentLedger)
        {
            return _server.EquipmentManager.Update(code, equipmentLedger);
        }

        [WebApi("批量更新设备", "设备对象", "执行结果")]
        public ApiResponse<bool> BatchUpdate(List<EquipmentLedger> equipmentLedgers)
        {
            return _server.EquipmentManager.BatchUpdate(equipmentLedgers);
        }

        [WebApi("批量删除", "设备对象", "执行结果")]
        public ApiResponse<bool> BatchDeleteEquipment(List<string> codes)
        {
            return _server.EquipmentManager.BatchRemove(codes);
        }

        [WebApi("清除设备台账集合", "", "执行结果")]
        public ApiResponse<bool> ClearEquipment()
        {
            return _server.EquipmentManager.Clear();
        }

        #endregion 设备台账

        #region EAM物联接口

        [WebApi("获取物联参数", "设备编码", "")]
        public ApiResponse<JArray> GetIoTDevicePara(string deviceCode)
        {
            Dictionary<string, HashSet<string>> keyValuePairs1 = new Dictionary<string, HashSet<string>>();
            keyValuePairs1.Add("sdfsa", new HashSet<string>() { "1", "2" });
            var json = JsonHelper.JsonSerialize(keyValuePairs1);
            if (string.IsNullOrEmpty(deviceCode))
                return ApiResponse<JArray>.Fail("参数错误。");

            var device = _server.DataManager.DriverGroups.Values.Where(x => x.DriverNO == deviceCode).FirstOrDefault();
            if (device == null)
                return ApiResponse<JArray>.Fail($"未找到 {deviceCode} 设备。");

            return JArray.FromObject(device.Groups.SelectMany(g => g.Items).Select(t => new
            {
                t.Name,
                t.FullName,
                t.Description,
                VarTypeValue = t.Address.VarType,
                VarTypeName = t.Address.VarType.ToString(),
                t.Unit,
                GroupName = t.Parent is IGroup group ? group.Name : "",
            })).ToResponse();
        }

        [WebApi("获取物联变量实时值", "设备编码,多个变量全称", "")]
        public ApiResponse<JArray> GetIoTRealValue(string deviceCode, HashSet<string> fullNames)
        {
            if (string.IsNullOrEmpty(deviceCode) || !fullNames.Any()) return ApiResponse<JArray>.Fail("参数错误。");
            var device = _server.DataManager.DriverGroups.Values.Where(x => x.DriverNO == deviceCode).FirstOrDefault();
            if (device == null) return ApiResponse<JArray>.Fail($"未找到 {deviceCode} 设备。");
            var query = fullNames.Except(device.Groups.SelectMany(x => x.Items).Select(x => x.FullName));

            return JArray.FromObject(device.Groups.SelectMany(x => x.Items)
                .Where(x => fullNames.Contains(x.FullName))
                .Select(x =>
                {
                    return new
                    {
                        x.Name,
                        x.FullName,
                        x.Description,
                        Value = x.Value is null ? "" : x.Value.ToString(),
                        TimeStampUnix = x.TimeStamp.DateTimeToUnix(),
                        SyncTimeUnix = DateTime.Now.DateTimeToUnix(),
                        QualityValue = x.Quality,
                        QualityName = x.Quality.ToString()
                    };
                })).ToResponse(query.Any() ? $"传入参数中：{string.Join(",", query)} 变量未找到！" : "");
        }

        [WebApi("获取多个取物联变量实时值", "设备编码,多个变量全称", "")]
        public ApiResponse<Dictionary<string, JArray>> GetMultiIoTRealValue(Dictionary<string, HashSet<string>> keyValuePairs)
        {
            Dictionary<string, JArray> result = new Dictionary<string, JArray>();
            foreach (var item in keyValuePairs)
            {
                result.Add(item.Key, GetIoTRealValue(item.Key, item.Value).Data ?? new JArray());
            }
            return result.ToResponse();
        }

        [WebApi("获取物联设备状态", "多个变量全称", "")]
        public ApiResponse<Dictionary<string, JObject>> GetIoTDeviceState(HashSet<string> deviceCode)
        {
            var result = new Dictionary<string, JObject>();
            if (!deviceCode.Any()) return ApiResponse<Dictionary<string, JObject>>.Fail("参数错误。");
            var query = deviceCode.Except(_server.DataManager.DriverGroups.Values.Select(x => x.DriverNO)).ToList();
            var devices = _server.DataManager.DriverGroups.Values.Where(x => deviceCode.Contains(x.DriverNO));
            foreach (var d in devices)
            {
                var tag = d.Groups.SelectMany(g => g.Items).Where(t => t.Name == "WorkState").FirstOrDefault();
                if (tag is null) continue;
                result.Add(d.DriverNO, JObject.FromObject(new
                {
                    tag.Name,
                    tag.Description,
                    Value = tag.Value.ToString(),
                    ValueName = ((WorkState)int.Parse(tag.Value.ToString())).ToString(),
                    TimeStampUnix = tag.TimeStamp.DateTimeToUnix(),
                    SyncTimeUnix = DateTime.Now.DateTimeToUnix(),
                    d.DriverNO,
                    tag.FullName
                }));
            }
            return result.ToResponse(query.Any() ? $"传入参数中：{string.Join(",", query)} 设备未找到！" : "");
        }

        #endregion EAM物联接口

        [WebApi("热重启模组", "", "执行结果")]
        public ApiResponse<bool> Restart()
        {
            var res = _server.Restart();
            return res.ToResponse<bool>();
        }

        [WebApi("获取服务是否完成初始化状态", "", "执行结果")]
        public ApiResponse<bool> ModuleInit()
        {
            var res = _server.DataManager.IsInit;
            return res.ToResponse<bool>();
        }

        [WebApi("获取设备的工序集合", "", "工序集合")]
        public ApiResponse<List<string>> GetEquipmentsProcess()
        {
            var equipments = GetEquipments(new EquipmentQueryInput { PageSize = 10000 }).Data.Rows;
            var data = equipments.Where(a => !string.IsNullOrWhiteSpace(a.processName)).Select(a => a.processName).Distinct().ToList();
            return data.ToResponse();
        }

        [WebApi("获取指定工序的设备集合", "工序名", "设备集合")]
        public ApiResponse<List<string>> GetEquipmentsProcessCollection(string processName)
        {
            var equipments = GetEquipments(new EquipmentQueryInput { PageSize = 10000 }).Data.Rows;
            var data = equipments.Where(a => a.processName == processName).Select(a => a.code).ToList();
            return data.ToResponse();
        }

        [WebApi("获取设备实时参数", "设备资产编码", "设备参数集合")]
        public ApiResponse<List<RunTimeTagModel>> GetEquipmentRuntimeData(string AssetCode)
        {
            return _server.DataManager.GetEquipmentRuntimeData(AssetCode);
        }

        [WebApi("获取运行时设备", "设备资产编码", "设备参数集合")]
        public ApiResponse<IDriver> GetRuntimeDriver(string AssetCode)
        {
            return _server.DataManager.GetRuntimeDriver(AssetCode);
        }

        [WebApi("获取运行时设备", "设备资产编码", "设备参数集合")]
        public ApiResponse<DeviceOutput> GetDeviceInfo(string AssetCode)
        {
            return new ApiResponse<DeviceOutput>();
        }
    }

    public class RegDriverInfo
    {
        public string Name { get; set; }

        public int Number { get; set; }

        public string ExpiryDate { get; set; }
    }

    public class DeviceApiReq
    {
        /// <summary>
        /// 设备编码
        /// </summary>
        public string AssectCode { get; set; }

        public object Parameter { get; set; }
    }

    public class DeviceOutput
    {
        public string Name { get; set; }

        public string FullName { get; set; }

        public string AssetCode { get; set; }

        public string ParentName { get; set; }
    }
}